﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DotNetExtensions.Core.Helpers
{
    public class TypeInfo
    {
        public string Assembly { get; set; }
        public string Module { get; set; }
        public string FullName { get; set; }
        public bool IsBasic { get; set; }

        public TypeInfo(Type type, bool basic = false)
        {
            if (type == null) return;
            this.FullName = type.FullName;
            this.Assembly = type.Assembly.FullName.Substring(0, type.Assembly.FullName.IndexOf(','));
            this.Module = type.Module.Name;
            this.IsBasic = basic;
        }

        public TypeInfo(string assemblyName, string typeFullName, bool basic)
        {
            this.FullName = typeFullName;
            this.Assembly = assemblyName;
            this.IsBasic = basic;
        }

        public TypeInfo(string assemblyName, string typeFullName)
        {
            this.FullName = typeFullName;
            this.Assembly = assemblyName;
            this.IsBasic = false;
        }

        public Type Resolve()
        {
            if (this.IsBasic)
            {
                return Type.GetType(this.FullName);
            }
            else
            {
                var clazz = IOC.ContainerBuilder.Default.Assemblies.Where(x => x.FullName.StartsWith(this.Assembly)).SelectMany(z => z.GetTypes()).Where(m => m.FullName == this.FullName);
                if (clazz.Any()) return clazz.First();
            }
            throw new Exception("初始化类型失败，类型" + FullName + ",所在程序集" + Assembly + "未找到相关信息。");
        }
        public Type Resolve(ICollection<Assembly> assemblies)
        {
            Type type = this.Resolve();
            if (type == null)
            {
                var clazz = assemblies.Where(x => x.FullName.Substring(0, x.FullName.IndexOf(',')) == this.Assembly).SelectMany(x => x.Modules).Where(y => y.Name == this.Module).SelectMany(z => z.GetTypes()).Where(m => m.FullName == this.FullName);
                if (clazz.Any()) return clazz.First();
            }
            return type;
        }

        public static TypeInfo Parse(string value)
        {
            return JsonConvert.DeserializeObject<TypeInfo>(value);
        }

        public string Serialize()
        {
            return JsonConvert.SerializeObject(this);
        }
    }
}
